package com.tarena.lbs.coupon.service.impl;

import com.github.xiaoymin.knife4j.core.util.Assert;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.common.enums.PassportResultEnum;
import com.tarena.lbs.coupon.api.pojo.param.UserCouponsParam;
import com.tarena.lbs.coupon.dao.repository.UserCouponsRepository;
import com.tarena.lbs.coupon.pojo.po.CouponPO;
import com.tarena.lbs.coupon.pojo.query.CouponQuery;
import com.tarena.lbs.coupon.pojo.query.UserCouponCodeQuery;
import com.tarena.lbs.coupon.pojo.query.UserCouponQuery;
import com.tarena.lbs.coupon.pojo.vo.UserCouponsVO;
import com.tarena.lbs.coupon.service.UserCouponsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;



@Service
@Slf4j
public class UserCouponsServiceImpl implements UserCouponsService {
    @Autowired
    UserCouponsRepository userCouponsRepository;

    @Override
    public UserCouponsVO receiveDetail(UserCouponCodeQuery query) {
        log.info("查看优惠券码的二维码图片的业务：{}" + query);
        UserCouponsVO vo = userCouponsRepository.receiveDetail(query);
        log.info("查询结果：{}", vo);
        return vo;
    }

    @Override
    public List<Void> receiveCoupon(UserCouponsParam param) throws BusinessException {
        Long start = System.currentTimeMillis();
        try {
            // 1.从参数中获取用户ID
            Integer userId = param.getUserId();
            Asserts.isTrue(userId == null, new BusinessException("-2", "用户ID不能为空"));
            log.info("用户ID:{}",userId);

            // 2.检查优惠券是否存在
            CouponPO couponPO = checkAndGetCoupon(param);
            Asserts.isTrue(couponPO == null, new BusinessException("-3", "优惠券不存在"));

            // 3.检查优惠券是否已达到领取上限
            // 当已使用数量小于最大限制时，还可以继续领取
            if (couponPO.getUsageNum() >= couponPO.getMaxUsageLimit()) {
                throw new BusinessException("-1", "优惠券已抢完");
            }

            log.info("领取优惠券开始：{}",couponPO);

            // 4.设置优惠券相关信息
            param.setCouponName(couponPO.getCouponName());
            param.setCouponType(couponPO.getCouponType());
            param.setCouponValue(couponPO.getDiscountValue());

            // 5.参数验证
            validateReceiveCouponParam(param, couponPO);

            // 记录参数信息用于调试
            log.info("准备领取优惠券，参数信息：{}", param);

            // 6.执行领取逻辑，将用户ID、优惠券ID保存到数据库中
            userCouponsRepository.receiveCoupon(param);

            // 7.增加优惠券已使用数量
            userCouponsRepository.incrementCouponUsage(param.getCouponId());

            log.info("用户领取优惠券成功");

            Long end = System.currentTimeMillis();
            log.info("领取优惠券的业务完成，用时：{}ms", (end-start));
        } catch (BusinessException e) {
            Long end = System.currentTimeMillis();
            log.error("领取优惠券业务失败，用时：{}ms，错误：{}", (end-start), e.getMessage());
            throw e;
        } catch (Exception e) {
            Long end = System.currentTimeMillis();
            log.error("领取优惠券业务异常，用时：{}ms，错误：{}", (end-start), e.getMessage(), e);
            throw new BusinessException("-500", "系统异常，请稍后重试");
        }
        return null;
    }

    /**
     * 验证领取优惠券参数
     * @param param 用户优惠券参数
     * @param couponPO 优惠券信息
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateReceiveCouponParam(UserCouponsParam param, CouponPO couponPO) throws BusinessException {
        if (param.getCouponId() == null) {
            throw new BusinessException("-4", "优惠券ID不能为空");
        }
        if (param.getCouponCode() == null && param.getCouponCode().isEmpty()) {
            throw new BusinessException("-5", "优惠券编码不能为空");
        }
        if (param.getCouponType() == null) {
            throw new BusinessException("-7", "优惠券类型不能为空");
        }
        if (param.getCouponValue() == null) {
            throw new BusinessException("-8", "优惠券面值不能为空");
        }
    }

    private CouponPO checkAndGetCoupon(UserCouponsParam param) {
        log.info("检查优惠券领取上限的仓储层：{}",param);
        CouponPO couponPO = userCouponsRepository.checkAndGetCoupon(param);
        log.info("检查结果：{}",couponPO);
        return couponPO;
    }


    @Override
    public List<UserCouponsVO> receiveList(UserCouponQuery couponQuery) {
        log.info("用户领取优惠券列表的业务:{}",couponQuery);
        List<UserCouponsVO> vos = userCouponsRepository.receiveList(couponQuery);
        log.info("用户领取优惠券列表结果:{}",vos);
        return vos;
    }
}